package tuding.android.bigplanettracks;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import tuding.android.bigplanettracks.util.Preferences;
import tuding.android.bigplanettracks.util.Task;
import tuding.android.bigplanettracks.util.TaskRunner;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
/**
 *Activity that deals with specific requirement when app got lunch, such as splash screen or EULA in the future. 
 *
 */
public class LunchActivity extends Activity implements TaskRunner, OnClickListener, OnCancelListener{
    //the first step of lunch
    private static final int LAUNCH_STEP_1=0;
    private static final int LAUNCH_STEP_2=1;
    private static final int VERSION_UPDATE_CHECK = 99;
    private static final String UPDATE_REQUIRED = "update_required";
    private static final String LAST_UPDATED_PROMPT_KEY = "last_prompted";
    // We use a handler to send messages to the UI thread.
    protected Handler m_handler;
 // We keep a reference to the main content view so we can add/remove other
    // views. If we simply called Activity.addContentView(), then we can never
    // remove it, and overlaying 2 content views becomes difficult.
    private ViewGroup m_contentView;
    private Dialog  m_updateDialog;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Put up a splash screen.
        View view = createSplashView();
        // Wrap the content view in another layout so we can add/remove other
        // views to the screen such as the EULA view might comes in the future of tuding. Otherwise we can only add.
        // The Activity class has no removeContentView().
        m_contentView = new FrameLayout(this);
        m_contentView.addView(view);
        setContentView(m_contentView);
        // Create a handler in the UI thread.
        m_handler = new Handler();
     // In parallel to the start sequence, do the update check
        // if not already knowing that an update is available
        if (!Preferences.getBoolean(UPDATE_REQUIRED, false)){
            new Thread(new Task(VERSION_UPDATE_CHECK, null, this)).start();
        }
        // Go to step 1 after a short delay so we can show the splash screen.
        m_handler.postDelayed(new Task(LAUNCH_STEP_1, null, this), 1000);
    }
    private View createSplashView() {
        // Use a layout inflater to load pre-designed views.
        LayoutInflater layoutInflater = getLayoutInflater();

        // Create a view for the splash screen.
        View view = layoutInflater.inflate(R.layout.splashscreen, null);

        try {
            // Build a version string.
            StringBuilder builder = new StringBuilder();
            builder.append("");
            builder.append(TudingerApp.getApplication().getVersionName());
            // Add version information to the view.
            TextView captionText = (TextView)view.findViewById(R.id.caption);
            captionText.setText(builder.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }

        return view;
    }
    
    public void runTask(int id, Bundle bundle) {
        Intent intent;
        switch (id) {
        case LAUNCH_STEP_1:
         // Step 2 - update prompt
            if (Preferences.getBoolean(UPDATE_REQUIRED, false)) {
                if (intervalExpiredSinceLastUpdatePrompt()) {
                    showUpdateDialog();
                    break;
                }
            }
            //fall down to step2 after step_1
        case LAUNCH_STEP_2:
            intent = new Intent(this,BigPlanet.class);
            startActivity(intent);
            finish();
            break;
         // Separate from the startup sequence
        case VERSION_UPDATE_CHECK:
            // This is ran separately from the rest of the startup sequence if there is
            checkForUpdate();
            break;
        }
        
    }
    
    /**
     * This function is run every time the application is started normally
     *  and the update flag is not set .This function ignores the update interval and checks every time
     * The update interval is used in displaying the dialog instead
     */
    private void checkForUpdate(){
        try {
            // Retrieve the latest version number and update the time of the check
            URL url = new URL(getResources().getString(R.string.UpdateVersionFile));
            InputStreamReader isr = new InputStreamReader(url.openStream());
            BufferedReader in = new BufferedReader(isr, 100);
            String inputLine = in.readLine();
            if (inputLine == null) return;
            int latest_code = Integer.parseInt(inputLine);
            in.close();
            isr.close();
            // Compare the retrieved version with the current version and, if needed,
            //   save the flag to let app know to prompt for update on the next launch
            int current_code = TudingerApp.getApplication().getVersionCode();
            if (latest_code > current_code) {
                Preferences.put(UPDATE_REQUIRED, true);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * Shows the update prompt dialog
     * Resents a value used to make sure that the update dialog is not
     * shows more frequently than the update time interval specifies
     */
    private void showUpdateDialog(){
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(getString(R.string.update_reguired_msg));
        builder.setPositiveButton("Yes", this);
        builder.setNegativeButton("No", this);
        builder.setOnCancelListener(this);
        m_updateDialog = builder.create();
        m_updateDialog.show();
        // Save the last time of the prompt dialog show (now)
        long now_ms = System.currentTimeMillis();
        Preferences.put(LAST_UPDATED_PROMPT_KEY, now_ms);
        // Hide the update flag. Even if the user fails to complete the update
        // the update check is ran on every application start, so the flag
        // will just come back up the next time
        Preferences.put(UPDATE_REQUIRED, false);
    }
    
    /**
     * This function checks whether a specified time interval has expired
     * since the update prompt dialog was last explained
     * @return - did the time interval expire?
     */
    private boolean intervalExpiredSinceLastUpdatePrompt(){
        long now_ms = System.currentTimeMillis();
        long last_ms = Preferences.getLong(LAST_UPDATED_PROMPT_KEY);
        String max_interval_sec_str = getString(R.string.UpdateIntervalSec);
        long max_interval_ms = Long.parseLong(max_interval_sec_str) * 1000;
        long interval_ms = now_ms - last_ms;
        return interval_ms > max_interval_ms;
    }
    
    public void onClick(DialogInterface dialog, int which) {
        if (m_updateDialog == dialog) {
            m_updateDialog = null;
            if (which == DialogInterface.BUTTON_POSITIVE) {
                // Go to the Market, exit the app
                try {
                    //Here we have 2 choices, one is to get from market, another is directly from our server
                    //String updateUri = "market://details?id=" + getPackageName();
                    String updateUri = getString(R.string.update_uri);
                    Intent intent = new Intent(
                            Intent.ACTION_VIEW,
                            Uri.parse(updateUri));
                    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
                    startActivity(intent);
                    finish();
                } catch (ActivityNotFoundException e) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(this);
                    builder.setMessage(getString(R.string.update_market_err_msg))
                            .setPositiveButton("Close", null);
                    builder.show();
                }
            } else {
                // Go to the next step.
                runOnUiThread(new Task(LAUNCH_STEP_2, null, this));
            }
        }
    }
    public void onCancel(DialogInterface dialog) {
       if (m_updateDialog == dialog) {
            m_updateDialog = null;
            // Go to the next step.
            runOnUiThread(new Task(LAUNCH_STEP_2, null, this));
        }
    }
            
}
